home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / pcpilot.arc / SCR.ARC / SCR.C < prev    next >
Text File  |  1990-01-14  |  15KB  |  537 lines

  1. /* ------------------------------------------------------------------------ */
  2. /*                                SCR.C                                     */
  3. /*             See pg. 162 of Systems Programming in Turbo C                */
  4. /*                                                                          */
  5. /* ------------------------------------------------------------------------ */
  6.  
  7. #include <dos.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <mem.h>
  11. #include <ctype.h>
  12.  
  13. #include "kbd.h"
  14. #include "scr.h"
  15.  
  16. void ScrGetMode (struct Mode *ModePtr)
  17. /*
  18.     This function gets the current video mode, number of display columns,
  19.     and video page
  20. */
  21. {
  22.     unsigned char AhHold;
  23.  
  24.     _AH = 15;                        /* BIOS get video mode service */
  25.     geninterrupt (0x10);            /* BIOS video service */
  26.     AhHold = _AH;                    /* AH returns columns */
  27.     ModePtr->VideoMode = _AL;        /* AL returns mode */
  28.     ModePtr->Columns = AhHold;
  29.     ModePtr->VideoPage = _BH;        /* BH returns active page */
  30. }
  31.  
  32.  
  33. void ScrSetMode (struct Mode *ModePtr)
  34. /*
  35.     This function sets the video mode and display page
  36. */
  37. {
  38.     _AH = 0;                        /* BIOS set mode service */
  39.     _AL = ModePtr->VideoMode;        /* BIOS video service */
  40.     geninterrupt (0x10);            /* INT 10H
  41.  
  42.     _AH = 5;                        /* BIOS set active page service */
  43.     _AL = ModePtr->VideoPage;
  44.     geninterrupt (0x10);
  45. }
  46.  
  47.  
  48. void InitScr(void)
  49. {
  50.     if (*(char far *)0x00400049 == 7)    {
  51.         VideoSeg = 0xb000;
  52.         VideoMode = MONO;
  53.     }
  54. }
  55.  
  56. void ScrGetCur (int *Col, int *Row, int Page)
  57. /*
  58.     This function assigns the current cursor position
  59. */
  60. {
  61.     _BH = (unsigned char)Page;
  62.     _AH = 3;                        /* BIOS get cursor position */
  63.     geninterrupt (0x10);
  64.  
  65.     *Row = _DH;
  66.     *Col = _DL;
  67. }
  68.  
  69.  
  70. void ScrSetCur (int Col, int Row, int Page)
  71. /*
  72.     This function the cursor position
  73. */
  74. {
  75.     _BH = (unsigned char)Page;
  76.     _DH = Row;
  77.     _DL = Col;
  78.     _AH = 2;                        /* BIOS set cursor position */
  79.     geninterrupt (0x10);
  80. }
  81.  
  82.  
  83. void ScrGetStyle (int *StartLine, int *StopLine)
  84. /*
  85.     This function determines the current cursor's shape
  86. */
  87. {
  88.     _BH = 0;    /* Get it for page 0, since all pages have same style */
  89.     _AH = 3;                        /* BIOS read cursor position */
  90.     geninterrupt (0x10);
  91.     *StartLine = _CH;
  92.     *StopLine = _CL;
  93. }
  94.  
  95.  
  96. void ScrSetStyle (int StartLine, int StopLine)
  97. /*
  98.     This function sets the cursor shape
  99. */
  100. {
  101.     _CH = StartLine;
  102.     _CL = StopLine;
  103.     _AH = 1;                        /* BIOS set cursor type */
  104.     geninterrupt (0x10);
  105. }
  106.  
  107. int GetKey(void)
  108. {
  109.     return (KbdGetC()&0x00ff);
  110. }
  111.  
  112. /* --------------------------- ScrPush/ScrPop ----------------------------- */
  113.  
  114. #define MAXSCREENS 10
  115.  
  116. static char *BufPtar [MAXSCREENS];    /* Elements of this array point to      */
  117.                                     /* the screen storage buffers on the    */
  118.                                     /* scree stack.                         */
  119. static int BufIdx = -1;                /* Index to BufPtar */
  120.  
  121. int ScrPush (void)
  122. /*
  123.     This fuction saves the contents of the current scree on the screen
  124.     stack.
  125. */
  126. {
  127.     int Vseg;
  128.  
  129.     if (++BufIdx >= MAXSCREENS)        /* Test if maximum stack size exceeded */
  130.         return (MAXTOOSMALL);
  131.                                     /* Allocate heap memory for one screen */
  132.     if ((BufPtar [BufIdx] = malloc (4000)) == NULL)    {
  133.         --BufIdx;                    /* Out of heap memory */
  134.         return (NOHEAP);
  135.     }
  136.  
  137.     if (*(char far *)0x00400049 == 7)    /* Test video mode */
  138.         Vseg = 0xb000;                /* Monochrome video memory */
  139.     else
  140.         Vseg = 0xb800;                /* Color video memory */
  141.  
  142.                                         /* Transfer video memory */
  143.     movedata (Vseg,0,FP_SEG ((char far *)BufPtar [BufIdx]),
  144.                 FP_OFF ((char far *)BufPtar [BufIdx]),4000);
  145.  
  146.     return (NOERROR);
  147. }
  148.  
  149.  
  150. int ScrPop (int Remove)
  151. /*
  152.     This function restores the most recently saved screen on the screen
  153.     stack, and removes the screen from the stack IF 'Remove' is nonzero.
  154. */
  155. {
  156.     int Vseg;
  157.  
  158.     if (BufIdx < 0)                        /* No screens to restore */
  159.         return (STACKEMPTY);
  160.  
  161.     if (*(char far *)0x00400049 == 7)    /* Test video mode */
  162.         Vseg = 0xb000;
  163.     else
  164.         Vseg = 0xb800;
  165.                                         /* Transfer video memory */
  166.     movedata (FP_SEG ((char far *)BufPtar [BufIdx]),
  167.                 FP_OFF ((char far *)BufPtar [BufIdx]), Vseg, 0, 4000);
  168.     if (Remove)                            /* Remove screen from stack */
  169.         free (BufPtar [BufIdx--]);
  170.  
  171.     return (NOERROR);
  172. }
  173.  
  174. /* ------------------------------------------------------------------------ */
  175.  
  176. #include <fcntl.h>
  177. #include <io.h>
  178.  
  179. int ScrReadWindow (char *Buffer, char *FileName)
  180. /*
  181.     This function reads the 4000-byte screen image file specified by
  182.     'FileName' (may contain a full path), into the buffer pointed to by
  183.     'Buffer'.
  184. */
  185. {
  186.     int FileHandle;
  187.  
  188.     if ((FileHandle = open (FileName,O_RDONLY | O_BINARY)) == -1)
  189.         return (OPENERR);
  190.     if (read (FileHandle, Buffer, 4000) != 4000)
  191.         return (READERR);
  192.     if (close (FileHandle) == -1)
  193.         return (CLOSERR);
  194.  
  195.     return (NOERROR);
  196. }
  197.  
  198.  
  199.  
  200. #include <stdarg.h>
  201.  
  202. void PutStr(int Col, int Row, int Attr, char *fmt, ...)
  203. {
  204.     va_list arg_ptr;
  205.     char t[100];
  206.  
  207.     va_start(arg_ptr, fmt);
  208.     vsprintf(t, fmt, arg_ptr);
  209.     ScrPutS(t, Attr, Row, Col);
  210.     va_end(arg_ptr);
  211. }
  212.  
  213. void Scroll(int x, int y, int xx, int yy, int direc, int attr)
  214. {
  215.     union REGS r;
  216.  
  217.     if (direc == 0) r.h.ah = 6;
  218.     else r.h.ah = 7;
  219.  
  220.     r.h.al = 1;
  221.     r.h.ch = y;
  222.     r.h.cl = x;
  223.     r.h.dh = yy;
  224.     r.h.dl = xx;
  225.     r.h.bh = attr;
  226.     int86(0x10, &r, &r);
  227. }
  228.  
  229. void ScrPutBox (int ULC, int ULR, int LRC, int LRR, int Style)
  230. /*
  231.     This function displays a box at the specified coordinates on the screen.
  232.     'Style' may be from 0 to 3.
  233. */
  234. {
  235.     register int i;
  236.     int Delta1, Delta2;
  237.  
  238.                                 /* Store the box characters for each style */
  239.     static char ulc [] = {218,201,213,214};
  240.     static char urc [] = {191,187,184,183};
  241.     static char llc [] = {192,200,212,211};
  242.     static char lrc [] = {217,188,190,189};
  243.     static char hl  [] = {196,205,205,196};
  244.     static char vl  [] = {179,186,179,186};
  245.  
  246.     int Vseg;                /* Segment address for video memory */
  247.     char far *Video;            /* Far pointer to video memory */
  248.  
  249.     Delta1 = (LRC - ULC) * 2;        /* Bytes between 2 vertical lines */
  250.     Delta2 = 160 - Delta1;            /* Bytes between right vertical   */
  251.                                     /* line and left vertical line of */
  252.                                     /* next row.                      */
  253.     if (*(char far *)0x00400049 == 7)    /* Test video mode */
  254.         Vseg = 0xb000;
  255.     else
  256.         Vseg = 0xb800;
  257.  
  258.     Video = MK_FP (Vseg, ULR*160+ULC*2);/* Initialize far pointer to */
  259.                                             /* upper left corner of box  */
  260.     *Video = ulc [Style];                    /* draw upper left corner    */
  261.     Video += 2;                                /* Skip attribute byte ???   */
  262.     for (i=1; i<=LRC-ULC-1; ++i)    {        /* Draw top horizontal line  */
  263.         *Video = hl [Style];
  264.         Video += 2;
  265.     }
  266.     *Video = urc [Style];                    /* Draw upper right corner   */
  267.     Video += Delta2;
  268.     for (i=1; i<=LRR-ULR-1; ++i)    {        /* Draw both vertical lines  */
  269.         *Video = vl [Style];                /* Left vertical line           */
  270.         Video += Delta1;
  271.         *Video = vl [Style];                /* Right vertical line         */
  272.         Video += Delta2;
  273.     }
  274.     *Video = llc [Style];                    /* Draw lower left corner    */
  275.     Video += 2;
  276.     for (i=1; i<=LRC-ULC-1; ++i)    {        /* Draw bottom horiz line    */
  277.         *Video = hl [Style];
  278.         Video +=2;
  279.     }
  280.     *Video = lrc [Style];                    /* Draw lower right corner   */
  281. }
  282.  
  283.  
  284. void StyleBox (int x, int y, int xx, int yy, int Attr)
  285. {
  286.     register int i;
  287.     int Delta1, Delta2;
  288.  
  289.     int Vseg;                    /* Segment address for video memory */
  290.     char far *Video;                /* Far pointer to video memory */
  291.  
  292.     Delta1 = (xx - x) * 2;            /* Bytes between 2 vertical lines */
  293.     Delta2 = 160 - Delta1;            /* Bytes between right vertical   */
  294.                                     /* line and left vertical line of */
  295.                                     /* next row.                      */
  296.     if (*(char far *)0x00400049 == 7)    /* Test video mode */
  297.         Vseg = 0xb000;
  298.     else
  299.         Vseg = 0xb800;
  300.  
  301.     Video = MK_FP (Vseg, y*160+x*2);    /* Initialize far pointer to */
  302.                                             /* upper left corner of box  */
  303.     *Video = 218;                            /* draw upper left corner    */
  304.     Video += 2;                                /* Skip attribute byte ???   */
  305.     for (i=1; i<=xx-x-1; ++i)    {            /* Draw top horizontal line  */
  306.         *Video = 196;
  307.         Video += 2;
  308.     }
  309.     *Video = 183;                            /* Draw upper right corner   */
  310.     Video += Delta2;
  311.     for (i=1; i<=yy-y-1; ++i)    {            /* Draw both vertical lines  */
  312.         *Video = 179;                        /* Left vertical line           */
  313.         Video += Delta1;
  314.         *Video = 186;                        /* Right vertical line         */
  315.         Video += Delta2;
  316.     }
  317.     *Video = 212;                            /* Draw lower left corner    */
  318.     Video += 2;
  319.     for (i=1; i<=xx-x-1; ++i)    {            /* Draw bottom horiz line    */
  320.         *Video = 205;
  321.         Video +=2;
  322.     }
  323.     *Video = 188;                            /* Draw lower right corner   */
  324.  
  325.                                             /* Attributes                */
  326.     SetAttrib(Attr, x, y, xx, y);            /* Top                       */
  327.     SetAttrib(Attr, x, y, x, yy);            /* Left side                 */
  328.     SetAttrib(Attr, xx, y, xx, yy);            /* Right side                */
  329.     SetAttrib(Attr, x, yy, xx, yy);            /* Bottom                    */
  330. }
  331.  
  332.  
  333. void ScrClear (int StartCol, int StartRow, int StopCol, int StopRow)
  334. {
  335.     _BH = 0x07;                        /* Use normal, white on black attribute */
  336.     _CH = StartRow;
  337.     _CL = StartCol;
  338.     _DH = StopRow;
  339.     _DL = StopCol;
  340.     _AX = 0x0600;                   /* BIOS scroll page up function */
  341.     geninterrupt (0x10);
  342. }
  343.  
  344.  
  345. void Cls(void)                        /* self explanetory */
  346. {
  347.     ScrClear (0,0,80,25);
  348. }
  349.  
  350. void HideCur(void)
  351. {
  352.     ScrSetCur (0, 26, 0);
  353. }
  354.  
  355. void RestCur(void)
  356. {
  357.     ScrSetStyle(0x06, 0x07);
  358.     ScrSetCur (0, 0, 0);
  359. }
  360.  
  361. void ShadowBox(int x, int y, int xx, int yy, int style, int attr)
  362. {
  363.     ClrScrn(x,y,xx,yy, attr);
  364.     DrawBox(x,y,xx,yy, style, attr);
  365.     SetAttrib(0x08, x+2, yy+1, xx+2, yy+1);
  366.     SetAttrib(0x08, xx+1, y+1, xx+2, yy+1);
  367.     nosound();
  368. }
  369.  
  370. void ClrScrn (int x, int y, int xx, int yy, int attr)
  371. {
  372.     _BH = attr;
  373.     _CL = x;
  374.     _CH = y;
  375.     _DL = xx;
  376.     _DH = yy;
  377.     _AX = 0x0600;                   /* BIOS scroll page up function */
  378.     geninterrupt (0x10);
  379. }
  380.  
  381.  
  382. ScrGetS (char *Buffer, int Attr, int Col, int Row, int Length, int Mode)
  383. /*
  384.     This function reads characters into 'Buffer', echoing the input starting
  385.     at 'Row' and 'Column', using video attribute 'Attr'. Characters are
  386.     read until an exit key (CR, Esc, or arrow) is encountered, or until the
  387.     number read is one less than the specified buffer size, 'Length'. If
  388.     the first key pressed is an exit key, the buffer is unaltered.
  389.     Otherwize, the buffer is initially filled with blanks and terminated
  390.     with a null; therefore, the resulting string will be blank-padded on the
  391.     right. The terminating exit key is not placed into the buffer. The
  392.     'Length' parameter should equal the 'sizeof' the receiving buffer.
  393.  
  394.     The 'Mode' parameter can specify one or more of the following features
  395.     (constants defined in SCR.H):
  396.  
  397.         NOFEAT:        No 'Mode' feature specified.
  398.         AUTOEXIT:    Exit field automatically when buffer is full.
  399.         UPPER:        Convert all letters to uppercase.
  400.         DIR:        Add '\' to ':' and no space fill on first char.
  401.  
  402.     The function returns one of the following codes indicating the field
  403.     exit key pressed by the user:
  404.  
  405.         -1    <Esc>
  406.          0    <CR>
  407.          1    <Left-Arrow>
  408.          2    <Right-Arrow>
  409.          3    <Up-Arrow>
  410.          4    <Down-Arrow>
  411.          5    Automatic exit (last character entered and AUTOEXIT selected).
  412. */
  413. {
  414.     register int CurCol, i;            /* current column/loop index            */
  415.     int Vseg;                    /* segment of video memory              */
  416.     int far *Video;                    /* far pointer to video memory          */
  417.     int Key;                        /* stores input key value               */
  418.     int FirstChar = 1;                /* flag to indicate the first character */
  419.     char *ChPt;                        /* for filling buffer with blanks       */
  420.     int far *IntFP;                    /* for filling buffer with blanks       */
  421.  
  422.     CurCol = Col;                        /* Initialize current column        */
  423.     if (*(char far *)0x00400049 == 7)
  424.         Vseg = 0xb000;
  425.     else
  426.         Vseg = 0xb800;
  427.  
  428.     Video = MK_FP (Vseg, Row*160+Col*2);
  429.     ScrSetStyle(0x06, 0x07);
  430.     ScrPutAttr(Attr, CurCol, Row, CurCol, Row);
  431.  
  432.     if (Mode == DIR)    {
  433.         CurCol += strlen(Buffer);
  434.         while (*Buffer)
  435.             *Video++ = (Attr << 8) | *Buffer++;
  436.     }
  437.     else
  438.         CurCol = Col;
  439.     ScrSetCur(CurCol,Row,0);
  440.  
  441.     for (;;)                /* Keyboard read loop */
  442.         switch (Key = KbdGetC ())
  443.             {
  444.             case 0x011b:        /* Escape                                    */
  445.                 return (-1);
  446.             case 0x4b00:        /* Left-Arrow                               */
  447.                 return (1);
  448.             case 0x4d00:        /* Right-Arrow                               */
  449.                 return (2);
  450.             case 0x4800:        /* Up-Arrow                                   */
  451.                 return (3);
  452.             case 0x5000:        /* Down-Arrow                               */
  453.                 return (4);
  454.             case 0x1c0d:        /* Return                                   */
  455.                 return (0);
  456.             case 0x0e08:        /* Backspace                               */
  457.                 if (CurCol > Col)    {
  458.                     *--Video = (Attr << 8) | ' ';
  459.                     *--Buffer = ' ';
  460.                     ScrSetCur (--CurCol,Row, 0);
  461.                 }
  462.                 break;
  463.             default:
  464.                 if (CurCol >= Col + Length - 1)        /* Test end of buffer   */
  465.                     break;
  466.                 if (Key&0x00ff == 0)            /* Test for non-ASCII char  */
  467.                     break;
  468.                 if (Mode & UPPER)                /* Uppercase conversion     */
  469.                     Key = toupper (Key&0x00ff);
  470.                 else
  471.                     Key &= 0x00ff;                /* Remove extended code     */
  472.                                     /* Place key in video memory & buffer   */
  473.                 *Video++ = (Attr << 8) | Key;
  474.                 *Buffer++ = Key;
  475.                 ScrSetCur (++CurCol, Row,0);    /* Update cursor position   */
  476.  
  477.  
  478.                 if (Mode == DIR)    {             /* Add '\' to ':'           */
  479.                     Key = toupper (Key&0x00ff);
  480.  
  481.                     if (Key == 0x003a)    {
  482.                         *Video++ = (Attr << 8) | 0x005c;
  483.                         *Buffer++ = 0x005c;
  484.                         ScrSetCur (++CurCol, Row,0);
  485.                     }
  486.                     *Buffer = '\0';
  487.                 }
  488.  
  489.  
  490.                 if (FirstChar)        /* Blank-fill buffer on first character */
  491.                     {
  492.                     FirstChar = 0;
  493.                     ChPt = Buffer;
  494.                     IntFP = Video;
  495.                     for (i=1; i<=Length-2; ++i)    {
  496.                         *ChPt++ = ' ';
  497.                         *IntFP++ = (Attr << 8) | ' ';
  498.                     }
  499.                     *ChPt = '\0';
  500.                 }
  501.                                                 /* Test for autoexit       */
  502.                 if ((CurCol >= Col + Length - 1) && (Mode & AUTOEXIT))
  503.                     return (5);                    /* Code for autoexit       */
  504.                 break;
  505.         }
  506. }
  507.  
  508.  
  509. void ScrPutAttr( int Attr, int StartCol, int StartRow,
  510.         int StopCol, int StopRow )
  511. {
  512.   register int Row, Col;
  513.   int Vseg, CharPerRow, Delta;
  514.   char far *Video;                            /* Far pointer to video memory. */
  515.  
  516.   if (*(char far *)0x00400049 == 7)         /* Test video mode              */
  517.     Vseg = 0xb000;
  518.   else
  519.     Vseg = 0xb800;
  520.  
  521.                    /* Initialize pointer to first attribute in video memory */
  522.   Video = MK_FP (Vseg,(StartRow*160+StartCol*2)+1);
  523.                                             /* Calculate characters per row */
  524.   CharPerRow = StopCol - StartCol + 1;
  525.                                   /* Calculate increment value between rows */
  526.   Delta = 160 - (StopCol - StartCol + 1) * 2;
  527.  
  528.   for( Row=1 ; Row<=StopRow-StartRow+1 ; ++Row ){
  529.      for( Col=1 ; Col<=CharPerRow; ++Col ){               /* Display a row */
  530.         *Video = Attr;                                 /* Write the attribute */
  531.         Video += 2;                         /* Increment to next attribute */
  532.      }
  533.      Video += Delta;                              /* Increment to next row */
  534.   }
  535. }
  536.  
  537.